import time
import requests
import os
import json
import logging

# 设置 API 端点和 API 密钥
api_key_aliyun= 'sk-3dcbcbe568a4435da699b467333c45f2'
url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/aa-detect"
api_key = api_key_aliyun  # 从环境变量中获取 API 密钥


logging.basicConfig(filename='app.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')


"""
调用API检查图像是否符合要求。

Args:
    content_type (str): 请求类型，必须是 "application/json"。
    authorization (str): API-Key，格式为 "Bearer <key>"。
    model (str): 需要调用的模型，例如 "animate-anyone-detect-gen2"。
    image_url (str): 需要检查的图像 URL。

Returns:
    dict: 包含检查结果的字典，包含以下字段：
        - output.check_pass (bool): 检查结果，True 表示通过，False 表示未通过。
        - output.bodystyle (str): 图像类型，"half" 表示半身图，"full" 表示全身图。
        - output.reason (str): 检查结果的原因。
        - request_id (str): 本次请求的系统唯一码。
"""
#AnimateAnyone 图像检测API
def post_animate_anyone_detect_gen2(img_url):
    # 设置请求头
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    # 设置请求体
    payload = {
        "model": "animate-anyone-detect-gen2",
        "input": {
            "image_url": img_url
        },
        "parameters": {}
    }

    # 发送 POST 请求
    response = requests.post(url, headers=headers, json=payload)

    # 打印响应结果
    if response.status_code == 200:
        print("图像检测-请求成功！")
        print("图像检测-响应内容:", response.json())  # 解析并打印 JSON 响应
        logging.info(f"图像检测-请求成功！{response.json()}")
        return response.json()
    else:
        print(f"图像检测-请求失败，状态码: {response.status_code}")
        print("图像检测-错误信息:", response.text)
        logging.error(f"图像检测-请求失败，状态码: {response.status_code}，错误信息: {response.text}")
        return response.text

"""
查询异步生成动画任务的当前状态。

Args:
    authorization (str): API-Key，格式为 "Bearer <key>"。
    task_id (str): 需要查询作业的 task_id。

Returns:
    dict: 包含任务状态信息的字典，包含以下字段：
        - output.task_id (str): 查询作业的 task_id。
        - output.task_status (str): 被查询作业的作业状态，可能的值包括 "PENDING"、"RUNNING"、"SUCCEEDED"、"FAILED" 和 "UNKNOWN"。
        - output.template_id (str): 平台输出的动作模板ID，可用于“Animate-Anyone 视频生成接口”的入参。
        - usage.template_duration (float): 本次请求生成模板时长计量，单位：秒。
        - usage.video_ratio (str): 本次请求生成视频模板的画幅类型，例如 "standard"。
        - request_id (str): 本次请求的系统唯一码。
"""
#动作骨架视频生成API
def post_generate_template(video_url):
    url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/aa-template-generation/'
    headers = {
        'X-DashScope-Async': 'enable',
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }
    data = {
        "model": "animate-anyone-template-gen2",
        "input": {
            "video_url": video_url
        },
        "parameters": {}
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(data))
    
    if response.status_code == 200:
        print(f"动作骨架视频生成-请求成功！{response.json()}")
        logging.info(f"请求成功！{response.json()}")
        return response.json()
    else:
        print(f"动作骨架视频生成-请求失败，状态码: {response.status_code}，错误信息: {response.text}")
        logging.error(f"动作骨架视频生成-请求失败，状态码: {response.status_code}，错误信息: {response.text}")
        return {"error": f"Request failed with status code {response.status_code}", "response": response.text}


"""
    查询异步生成动画任务的当前状态。

    Args:
        authorization (str): API-Key，格式为 "Bearer <key>"。
        task_id (str): 需要查询作业的 task_id。

    Returns:
        dict: 包含任务状态信息的字典，包含以下字段：
            - output.task_id (str): 查询作业的 task_id。
            - output.task_status (str): 被查询作业的作业状态，可能的值包括 "PENDING"、"RUNNING"、"SUCCEEDED"、"FAILED" 和 "UNKNOWN"。
            - output.template_id (str): 平台输出的动作模板ID，可用于“Animate-Anyone 视频生成接口”的入参。
            - usage.template_duration (float): 本次请求生成模板时长计量，单位：秒。
            - usage.video_ratio (str): 本次请求生成视频模板的画幅类型，例如 "standard"。
            - request_id (str): 本次请求的系统唯一码。
"""
#查询动作骨架视频生成任务状态
def get_task_status_pose(task_id):
    url = f"https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}"
    headers = {
        'Authorization': f'Bearer {api_key}'
    }
    
    response = requests.get(url, headers=headers)
    
    if response.status_code == 200:
        print(f"查询动作骨架视频生成任务状态-请求成功！{response.json()}")
        logging.info(f"查询动作骨架视频生成任务状态-请求成功！{response.json()}")
        return response.json()
    else:
        print(f"查询动作骨架视频生成任务状态-请求失败，状态码: {response.status_code}，错误信息: {response.text}")
        logging.error(f"查询动作骨架视频生成任务状态-请求失败，状态码: {response.status_code}，错误信息: {response.text}")
        response.raise_for_status()


"""
提交一个异步任务来生成动画。

Args:
    content_type (str): 请求类型，必须是 "application/json"。
    authorization (str): API-Key，格式为 "Bearer <key>"。
    async_header (str): 异步方式提交作业的标识，必须是 "enable"。
    model (str): 需要调用的模型，例如 "animate-anyone-gen2"。
    image_url (str): 用户上传的图片 URL，图像文件＜5M，宽高比≤2，最大边长≤4096，格式支持jpg、png、jpeg、bmp。上传图片仅支持HTTP链接，不支持本地路径。
    template_id (str): 动作模板ID，用于指明所需使用的动作模板，例如 "AACT.xxx.xxx-xxx.xxx"。
    use_ref_img_bg (bool, optional): 生成视频的背景控制，设为True时以输入图片的画面为背景生成视频，默认为False。
    video_ratio (str, optional): 选择按图片背景生成视频时，可选画幅为 "9:16" 或 "3:4"，默认为 "9:16"。

Returns:
    dict: 包含异步任务提交结果的字典，包含以下字段：
        - output.task_id (str): 提交异步任务的作业 id，用于查询实际作业结果。
        - output.task_status (str): 提交异步任务后的作业状态，例如 "PENDING"。
        - request_id (str): 本次请求的系统唯一码。
"""
#AnimateAnyone 生成视频API
def post_animate_anyone_gen2(image_url, template_id, use_ref_img_bg=False, video_ratio="9:16"):
    url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis/'
    headers = {
        'X-DashScope-Async': 'enable',
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }
    data = {
        "model": "animate-anyone-gen2",
        "input": {
            "image_url": image_url,
            "template_id": template_id
        },
        "parameters": {
            "use_ref_img_bg": use_ref_img_bg,
            "video_ratio": video_ratio
        }
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(data))
    
    if response.status_code == 200:
        print(f"生成视频-请求成功！{response.json()}")
        logging.info(f"生成视频-请求成功！{response.json()}")
        return response.json()
    else:
        print(f"生成视频-请求失败，状态码: {response.status_code}，错误信息: {response.text}")
        logging.error(f"生成视频-请求失败，状态码: {response.status_code}，错误信息: {response.text}")
        return {"error": f"Request failed with status code {response.status_code}", "response": response.text}

"""
查询异步生成动画任务的最终结果。

Args:
    authorization (str): API-Key，格式为 "Bearer <key>"。
    task_id (str): 需要查询作业的 task_id。

Returns:
    dict: 包含任务结果信息的字典，包含以下字段：
        - output.task_id (str): 查询作业的 task_id。
        - output.task_status (str): 被查询作业的作业状态，可能的值包括 "PENDING"、"PRE-PROCESSING"、"RUNNING"、"POST-PROCESSING"、"SUCCEEDED"、"FAILED" 和 "UNKNOWN"。
        - output.video_url (str): 平台输出的视频结果 URL，有效期为作业完成后24小时。
        - usage.video_duration (float): 本次请求生成视频时长计量，单位：秒。
        - usage.video_ratio (str): 本次请求生成视频的画幅类型，例如 "standard"。
        - request_id (str): 本次请求的系统唯一码。
"""
#查询异步生成动画任务的最终结果
def get_task_status_video(task_id):

    url = f"https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}"
    headers = {
        "Authorization": f"Bearer {api_key}"
    }

    # 发送 GET 请求
    response = requests.get(url, headers=headers)

    # 检查响应状态码
    if response.status_code == 200:
        print(f"查询异步生成动画任务的最终结果-请求成功！{response.json()}")
        logging.info(f"查询异步生成动画任务的最终结果-请求成功！{response.json()}")
        return response.json()  # 返回 JSON 格式的响应数据
    else:
        # 如果请求失败，抛出异常
        print(f"查询异步生成动画任务的最终结果-请求失败，状态码: {response.status_code}，错误信息: {response.text}")
        logging.error(f"查询异步生成动画任务的最终结果-请求失败，状态码: {response.status_code}，错误信息: {response.text}")
        response.raise_for_status()
        return {"error": f"Request failed with status code {response.status_code}", "response": response.text}



def main():
    img_url = "https://gitee.com/taodijianbai/aliyun_animate-anyone/raw/main/man1.png"
    video_url = "https://thumbsnap.com/i/MqzV1fk8.mp4"
    #0调用一个图像检测函数
    img_return = post_animate_anyone_detect_gen2(img_url)
    # print(img_return)
    # print(img_return['output']['check_pass'])
    img_tf = img_return['output']['check_pass']
    if img_tf:

        #1请求生成一个动作模板
        pose_return = post_generate_template(video_url)
        pose_return_task_id = pose_return['output']['task_id']
        print(f'pose_return_task_id:{pose_return_task_id}')

        #2获取生成的动作模板的 ID
        template_id = ''
        while True:
            task_pose_return = get_task_status_pose(pose_return_task_id)
            if task_pose_return['output']['task_status'] == 'SUCCEEDED':
                template_id = task_pose_return['output']['template_id']
                print(f'template_id:{template_id}')
                break
            time.sleep(30)
        
        #3使用这个模板和一张图片来生成一个动画视频
        video_return = post_animate_anyone_gen2(img_url, template_id)
        video_return_task_id = video_return['output']['task_id']
        print(f'video_return_task_id:{video_return_task_id}')
        #4获取生成的视频的 URL
        while True:
            task_video_return = get_task_status_video(video_return_task_id)
            if task_video_return['output']['task_status'] == 'SUCCEEDED':
                video_url = task_video_return['output']['video_url']
                print(f'video_url:{video_url}')
                break
            time.sleep(30)
    

if __name__ == '__main__':
    main()